package com.springboot.framework.controller;

import com.springboot.framework.annotation.ACS;
import com.springboot.framework.controller.request.CouponsReceiveBean;
import com.springboot.framework.dao.entity.Coupons;
import com.springboot.framework.enums.CouponsEnum;
import com.springboot.framework.enums.Errors;
import com.springboot.framework.enums.StatusEnum;
import com.springboot.framework.exception.BusinessException;
import com.springboot.framework.model.BuyerModel;
import com.springboot.framework.model.CouponsModel;
import com.springboot.framework.model.UserCouponsModel;
import com.springboot.framework.service.BuyerService;
import com.springboot.framework.service.CouponsService;
import com.springboot.framework.service.UserCouponsService;
import com.springboot.framework.utils.ResponseVoUtil;
import com.springboot.framework.vo.CouponsVO;
import com.springboot.framework.vo.ResponseVO;
import com.springboot.framework.vo.UserCouponsVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author SWF
 * @date 2019/6/20 13:59
 **/
@Api(description = "【买家】优惠券领取与使用")
@RestController
@RequestMapping("/buyer/coupons")
public class BuyerCouponsController {

    @Resource
    private UserCouponsService userCouponsService;

    @Resource
    private BuyerService buyerService;

    @Resource
    private CouponsService couponsService;

    @ACS(allowAnonymous = true)
    @ApiOperation(value = "买家领取优惠券", notes = "买家领取优惠券")
    @PostMapping("/receive")
    public ResponseVO<UserCouponsModel> receive(@RequestBody CouponsReceiveBean bean) {
        BuyerModel buyerModel = buyerService.getByOpenId(bean.getOpenId());
        if (buyerModel == null) {
            throw new BusinessException("请登录");
        }
        int checkCount = userCouponsService.getRecordCount(buyerModel.getId(),bean.getCouponsId());
        if(checkCount > 0){
            throw new BusinessException(Errors.COUPONS_HAVE_TO_RECEIVE);
        }
        CouponsModel couponsModel = couponsService.get(bean.getCouponsId());
        if(couponsModel == null){
            throw new BusinessException(Errors.COUPONS_NOT_EXIST);
        }
        // 判断领券活动状态，是否可领券
        if (!couponsModel.getStatus().equals(StatusEnum.NORMAL.getCode())) {
            throw new BusinessException(Errors.COUPONS_ACTIVITY_HAVE_DISABLE);
        }
        UserCouponsModel userCouponsModel = userCouponsService.receive(buyerModel, couponsModel);
        return ResponseVoUtil.success(userCouponsModel);
    }

    @ACS(allowAnonymous = true)
    @ApiOperation(value = "查看拥有的所有优惠券", notes = "查看拥有的所有优惠券")
    @GetMapping("/list")
    public ResponseVO<Object> listUserCoupons(@RequestParam String openId) {
        BuyerModel buyerModel = buyerService.getByOpenId(openId);
        if (buyerModel == null) {
            throw new BusinessException("请登录");
        }
        List<UserCouponsModel> userCouponsModels = userCouponsService.list(buyerModel.getId());
        if (userCouponsModels != null) {
            List<UserCouponsVO> unused = new ArrayList<>();
            List<UserCouponsVO> used = new ArrayList<>();
            List<UserCouponsVO> disabled = new ArrayList<>();
            for (UserCouponsModel userCouponsModel : userCouponsModels) {
                UserCouponsVO userCouponsVO = new UserCouponsVO();
                BeanUtils.copyProperties(userCouponsModel, userCouponsVO);
                userCouponsVO.setCouponsAmount(userCouponsModel.getCouponsAmount());
                if (userCouponsVO.getStatus().equals(CouponsEnum.STATUS_UNUSED.getCode())) {
                    unused.add(userCouponsVO);
                } else if (userCouponsVO.getStatus().equals(CouponsEnum.STATUS_USED.getCode())) {
                    used.add(userCouponsVO);
                } else {
                    disabled.add(userCouponsVO);
                }
            }
            Map<String,List<UserCouponsVO>> map = new HashMap();
            map.put("unused", unused);
            map.put("used", used);
            map.put("disabled", disabled);
            return ResponseVoUtil.success(map);
        }
        return ResponseVoUtil.success(convertUserCouponsVO(userCouponsModels));
    }

    @ACS(allowAnonymous = true)
    @ApiOperation(value = "查看拥有的所有优惠券", notes = "查看拥有的所有优惠券")
    @GetMapping("/listForOrder")
    public ResponseVO<Object> listUserCouponsForOrder(@RequestParam String openId,@RequestParam String shopId,@RequestParam Integer amount) {
        BuyerModel buyerModel = buyerService.getByOpenId(openId);
        if (buyerModel == null) {
            throw new BusinessException("请登录");
        }
        List<UserCouponsModel> userCouponsModels = userCouponsService.listOfUnused(buyerModel.getId());
        if (userCouponsModels != null) {
            List<UserCouponsVO> unable = new ArrayList<>();
            List<UserCouponsVO> disable = new ArrayList<>();
            for (UserCouponsModel userCouponsModel : userCouponsModels) {
                UserCouponsVO userCouponsVO = new UserCouponsVO();
                BeanUtils.copyProperties(userCouponsModel, userCouponsVO);
                userCouponsVO.setCouponsAmount(userCouponsModel.getCouponsAmount());
                Date nowDate = new Date();
                if (userCouponsModel.getEffectiveDate().after(nowDate) | userCouponsModel.getExpiryDate().before(nowDate)) {
                    userCouponsVO.setNotMsg("该优惠券不在使用期限内");
                    disable.add(userCouponsVO);
                    continue;
                }
                if (userCouponsVO.getCouponsScope().equals(CouponsEnum.SCOPE_SHOP.getCode()) && !userCouponsVO.getShopId().equals(new Integer(shopId))) {
                    userCouponsVO.setNotMsg("该优惠券只能用于指定店铺");
                    disable.add(userCouponsVO);
                    continue;
                }
                if (userCouponsVO.getMinimumAmount() > amount) {
                    userCouponsVO.setNotMsg("商品金额没有达到优惠券使用金额");
                    disable.add(userCouponsVO);
                    continue;
                }
                unable.add(userCouponsVO);
            }
            Map map = new HashMap();
            map.put("unable", unable);
            map.put("disable", disable);
            return ResponseVoUtil.success(map);
        }
        return ResponseVoUtil.success(userCouponsModels);
    }


    @ACS(allowAnonymous = true)
    @ApiOperation(value = "查看可领取的优惠券", notes = "查看可以领取的优惠券")
    @GetMapping("/listCoupons")
    public ResponseVO<Object> listCoupons() {
        List<CouponsModel> couponsModelList = couponsService.list();
        return ResponseVoUtil.success(convertCouponsVOFromCoupons(couponsModelList));
    }

    @ACS(allowAnonymous = true)
    @ApiOperation(value = "查看可领取的优惠券", notes = "查看可以领取的优惠券")
    @GetMapping("/getCoupons")
    public ResponseVO<Object> getCoupons(@RequestParam Integer couponsId) {
        CouponsModel couponsModel = couponsService.get(couponsId);
        return ResponseVoUtil.success(convertCouponsVOFromCoupons(couponsModel));
    }

    private List<UserCouponsVO> convertUserCouponsVO(List<UserCouponsModel> userCouponsModelList) {
        List<UserCouponsVO> userCouponsVOS = userCouponsModelList.stream()
                .map(e -> {
                    UserCouponsVO userCouponsVO = new UserCouponsVO();
                    BeanUtils.copyProperties(e, userCouponsVO);
                    userCouponsVO.setCouponsAmount(e.getCouponsAmount());
                    return userCouponsVO;
                }).collect(Collectors.toList());
        return userCouponsVOS;
    }

    private CouponsVO convertCouponsVOFromCoupons(CouponsModel coupons){
        if(coupons == null){
            return null;
        }
        CouponsVO couponsVO = new CouponsVO();
        BeanUtils.copyProperties(coupons,couponsVO);
        return couponsVO;
    }

    private List<CouponsVO> convertCouponsVOFromCoupons(List<CouponsModel> couponsModels){
        if(couponsModels == null){
            return null;
        }
        List<CouponsVO> couponsVOS = couponsModels.stream()
                .map(e->convertCouponsVOFromCoupons(e))
                .collect(Collectors.toList());
        return couponsVOS;
    }
}
